﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Demo.DtoParameters;
using Demo.Entities;
using Demo.Helpers;
using Demo.Repository;
using Microsoft.CodeAnalysis.CSharp;

namespace Demo.Services
{
    public class CompanyService: ICompanyService
    {
        private readonly ICompanyRepository _companyRepository;
        private readonly IEmployeeService _employeeService;

        public CompanyService(ICompanyRepository companyRepository,IEmployeeService employeeService)
        {
            _companyRepository = companyRepository ?? throw new ArgumentNullException(nameof(companyRepository));
            _employeeService = employeeService ?? throw new ArgumentNullException(nameof(employeeService));
        }

        public async Task<PageList<Company>> GetCompaniesAsync(CompanyDtoParameters parameters)
        {
            return await _companyRepository.GetCompaniesAsync(parameters);
        }

        public async Task<Company> GetCompanyAsync(Guid companyId)
        {
            if (companyId.Equals(Guid.Empty)) throw new ArgumentNullException(nameof(companyId));

            return await _companyRepository.GetCompanyAsync(companyId);
        }

        public async Task<IEnumerable<Company>> GetCompaniesAsync(IEnumerable<Guid> companyIds)
        {
            if (companyIds == null) throw new ArgumentNullException(nameof(companyIds));

            return await _companyRepository.GetCompaniesAsync(companyIds);
        }

        public async Task<bool> AddCompany(Company company)
        {
            if (company == null) throw new ArgumentNullException(nameof(company));

            return await AddCompanies(new List<Company> {company});
        }

        public async Task<bool> AddCompanies(IEnumerable<Company> companies)
        {
            if (companies == null) throw new ArgumentNullException(nameof(companies));
            foreach (var company in companies)
            {
                company.Id = Guid.NewGuid();
                if (company.Employees?.Count > 0)
                {
                    foreach (var employee in company.Employees)
                    {
                        employee.Id = Guid.NewGuid();
                    }
                }

                _companyRepository.AddCompany(company);
            }

            return await SaveAsync();
        }

        public async void DeleteCompany(Company company)
        {
            if (company == null) throw new ArgumentNullException(nameof(company));

            var employees = await _employeeService.GetEmployeesAsync(company.Id, null);

            _employeeService.DeleteEmployees(employees.ToArray());

            _companyRepository.DeleteCompany(company);
            await SaveAsync();
        }

        public void UpdateCompany(Company company)
        {
            if (company == null) throw new ArgumentNullException(nameof(company));

            _companyRepository.UpdateCompany(company);
        }

        public async Task<bool> CompanyExistsAsync(Guid companyId)
        {
            if (companyId.Equals(Guid.Empty)) throw new ArgumentNullException(nameof(companyId));

            return await _companyRepository.CompanyExistsAsync(companyId);
        }

        public async Task<bool> SaveAsync()
        {
            return (await _companyRepository.SaveAsync()) > 0;
        }
    }
}